#include <stdlib.h>
#include <string.h>

#include "dtk_debug.h"
#include "dtk_button.h"

const DString DTK_TYPE_BUTTON = "DTKButton";

void button_down  (DTKActor* self, DTKMouseButtonEventArgs* ev)
{
    DTKButton* button = (DTKButton*) self;

    DTK_TYPE_ASSERT (self, DTK_TYPE_BUTTON);
    dtk_vsm_goto_state(button->vsm, BS_PRESSED);
    dtk_signal_emit(self, "pressed", NULL);
    return;
}

void button_up  (DTKActor* self, DTKMouseButtonEventArgs* ev)
{
    DTKButton* button = (DTKButton*) self;
    DTK_TYPE_ASSERT (self, DTK_TYPE_BUTTON);
    dtk_vsm_goto_state(button->vsm, BS_NORMAL);
    dtk_signal_emit(self, "released", NULL);
    dtk_signal_emit(self, "clicked", NULL);
    return;
}

static void action_normal(DInt state, DPointer usrdata)
{
    DColor color = {0, 0, 0, 0xff};
    DTKActor* actor = (DTKActor*) usrdata;
    dtk_actor_set_bgcolor (actor, &color);
    dtk_layout_redraw(dtk_actor_get_layout(actor), NULL, DTK_FALSE);
    return;
}

static void action_pressed(DInt state, DPointer usrdata)
{
    DColor color = {0xff, 0xff, 0, 0xff};
    DTKActor* actor = (DTKActor*) usrdata;
    dtk_actor_set_bgcolor (actor, &color);
    dtk_layout_redraw(dtk_actor_get_layout(actor), NULL, DTK_FALSE);
    return;
}

DTKActor* dtk_button_new(DString label)
{
    DTKButton*              button;
    DTKVisualState*         state;
    DTKVisualStateGroup*    group;
    DTKActor*               actor;
    DTKActorCallback*       funcs;

    actor = dtk_actor_init (sizeof(DTKButton), DTK_TYPE_BUTTON,
        DACAPS_HASCONTENT, NULL);
    button = (DTKButton*)actor;

    button->vsm = dtk_vsm_create();
    group = dtk_vsg_create(0x01);
    dtk_vsm_add(button->vsm, group);
    state = dtk_vs_create(BS_NORMAL, (DPointer)button, action_normal);
    dtk_vsg_add(group, state, DTK_TRUE);
    state = dtk_vs_create(BS_PRESSED, (DPointer)button, action_pressed);
    dtk_vsg_add(group, state, DTK_FALSE);

    funcs = DTK_ACTOR_CALLBACK(actor);
    funcs->button_down = button_down;
    funcs->button_up = button_up;

    dtk_signal_register(actor, "pressed");
    dtk_signal_register(actor, "released");
    dtk_signal_register(actor, "clicked");
    dtk_signal_register(actor, "enter");
    dtk_signal_register(actor, "leave");    

    return actor;
}
